﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Reflection;
namespace Peer.Data
{
    public class DbUtils
    {
        public static T[] DataReaderToEntitiy<T>(DbDataReader reader)
        {
            string tmpColName = string.Empty;
            List<T> tc = new List<T>();
            T o;
            DbTableAttribute[] ota = typeof(T).GetCustomAttributes(typeof(DbTableAttribute), true) as DbTableAttribute[];
            if (null != ota && 1 == ota.Length)
            {
                while (reader.Read())
                {
                    o = Activator.CreateInstance<T>();
                    foreach (PropertyInfo info in typeof(T).GetProperties())
                    {
                        DbColumnAttribute[] oca = info.GetCustomAttributes(typeof(DbColumnAttribute), true) as DbColumnAttribute[];
                        if (null != oca && 1 == oca.Length)
                        {
                            tmpColName = oca[0].Name != string.Empty ? oca[0].Name : info.Name;
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                if (reader.GetFieldType(i) == info.PropertyType && string.Compare(reader.GetName(i), tmpColName, true) == 0)
                                {
                                    info.SetValue(o, reader[i], null);
                                }
                            }
                        }
                    }
                    tc.Add(o);
                }
            }

            return tc.ToArray();
        }
        public static T[] DataTableToEntitiy<T>(DataTable table)
        {
            string tmpColName = string.Empty;
            string tmpTabName = string.Empty;
            List<T> tc = new List<T>();
            T o;
            DbTableAttribute[] ota = typeof(T).GetCustomAttributes(typeof(DbTableAttribute), true) as DbTableAttribute[];
            tmpTabName = (ota[0].Name != string.Empty ? ota[0].Name : typeof(T).Name);
            if (null != ota && 1 == ota.Length && string.Compare(tmpTabName,table.TableName,true)==0)
            {
                foreach (DataRow row in table.Rows)
                {
                    o = Activator.CreateInstance<T>();
                    foreach (PropertyInfo info in typeof(T).GetType().GetProperties())
                    {
                        DbColumnAttribute[] oca = info.GetCustomAttributes(typeof(DbColumnAttribute), true) as DbColumnAttribute[];
                        if (null != oca && 1 == oca.Length)
                        {
                            tmpColName = oca[0].Name != string.Empty ? oca[0].Name : info.Name;
                            foreach (DataColumn col in table.Columns)
                            {

                                if (col.DataType == info.PropertyType && string.Compare(col.ColumnName,tmpColName,true)==0)
                                {
                                    info.SetValue(o, row[col], null);
                                }
                            }
                        }
                    }
                    tc.Add(o);
                }
            }
            return tc.ToArray();
        }
        public static string GetInsertSQL(object o)
        {
            if (o != null)
            {
                string tmpColName = string.Empty;
                string tmpTabName = string.Empty;
                DbTableAttribute[] ota = o.GetType().GetCustomAttributes(typeof(DbTableAttribute), true) as DbTableAttribute[];
                tmpTabName = (ota[0].Name != string.Empty ? ota[0].Name : o.GetType().Name);
                string strN = string.Empty;
                string strV = string.Empty;
                foreach (PropertyInfo info in o.GetType().GetProperties())
                {
                    DbColumnAttribute[] oca = info.GetCustomAttributes(typeof(DbColumnAttribute), true) as DbColumnAttribute[];
                    if (null != oca && 1 == oca.Length)
                    {
                        tmpColName = oca[0].Name != string.Empty ? oca[0].Name : info.Name;
                        strN += tmpColName + ",";
                        strV += string.Format("{0},",FormatValSql(info.PropertyType,info.GetValue(o, null)));
                    }
                }
                strN = strN.TrimEnd(",".ToCharArray());
                strV = strV.TrimEnd(",".ToCharArray());
                return string.Format("insert {0}({1})values({2})", tmpTabName, strN, strV);
            }
            else
            {
                return null;
            }
        }
        public static string GetUpdateSQL(object o)
        {
            if (o != null)
            {
                string tmpColName = string.Empty;
                string tmpTabName = string.Empty;
                DbTableAttribute[] ota = o.GetType().GetCustomAttributes(typeof(DbTableAttribute), true) as DbTableAttribute[];
                tmpTabName = (ota[0].Name != string.Empty ? ota[0].Name : o.GetType().Name);
                string strN = string.Empty;
                string strV = string.Empty;
                foreach (PropertyInfo info in o.GetType().GetProperties())
                {
                    DbColumnAttribute[] oca = info.GetCustomAttributes(typeof(DbColumnAttribute), true) as DbColumnAttribute[];
                    if (null != oca && 1 == oca.Length)
                    {
                        tmpColName = oca[0].Name != string.Empty ? oca[0].Name : info.Name;
                        if (oca[0].IsPrimary)
                        {
                            strN += string.Format("{0}={1},", tmpColName,FormatValSql(info.PropertyType, info.GetValue(o, null)));
                        }
                        else
                        {
                            strV += string.Format("{0}={1},",tmpColName,FormatValSql(info.PropertyType,info.GetValue(o, null)));
                        }
                    }
                }
                strN = strN.TrimEnd(",".ToCharArray());
                strN = strN.Replace(",", " and ");
                strV = strV.TrimEnd(",".ToCharArray());
                return string.Format("update {0} set {1} where {2}", tmpTabName,strV,strN);
            }
            else
            {
                return null;
            }
        }
        public static string GetSelectSQL(object o)
        {
            if (o != null)
            {
                string tmpColName = string.Empty;
                string tmpTabName = string.Empty;
                DbTableAttribute[] ota = o.GetType().GetCustomAttributes(typeof(DbTableAttribute), true) as DbTableAttribute[];
                tmpTabName = (ota[0].Name != string.Empty ? ota[0].Name : o.GetType().Name);
                string strN = string.Empty;
                foreach (PropertyInfo info in o.GetType().GetProperties())
                {
                    DbColumnAttribute[] oca = info.GetCustomAttributes(typeof(DbColumnAttribute), true) as DbColumnAttribute[];
                    if (null != oca && 1 == oca.Length)
                    {
                        tmpColName = oca[0].Name != string.Empty ? oca[0].Name : info.Name;
                        if (oca[0].IsPrimary)
                        {
                            strN += string.Format("{0}={1},", tmpColName,FormatValSql(info.PropertyType, info.GetValue(o, null)));
                        }
                    }
                }
                strN = strN.TrimEnd(",".ToCharArray());
                strN = strN.Replace(",", " and ");
                return string.Format("select * from {0} where {1}", tmpTabName,strN);
            }
            else
            {
                return null;
            }
        }
        public static string GetDeleteSQL(object o)
        {
            if (o != null)
            {
                bool isDelTag = false;
                string tmpColName = string.Empty;
                string tmpU=string.Empty;
                string tmpTabName = string.Empty;
                DbTableAttribute[] ota = o.GetType().GetCustomAttributes(typeof(DbTableAttribute), true) as DbTableAttribute[];
                tmpTabName = (ota[0].Name != string.Empty ? ota[0].Name : o.GetType().Name);
                string strN = string.Empty;
                foreach (PropertyInfo info in o.GetType().GetProperties())
                {
                    DbColumnAttribute[] oca = info.GetCustomAttributes(typeof(DbColumnAttribute), true) as DbColumnAttribute[];
                    if (null != oca && 1 == oca.Length)
                    {
                        tmpColName = oca[0].Name != string.Empty ? oca[0].Name : info.Name;
                        if (oca[0].IsPrimary)
                        {
                            strN += string.Format("{0}={1},", tmpColName,FormatValSql(info.PropertyType,info.GetValue(o, null)));
                        }
                        if (oca[1].IsDelTag)
                        {
                            isDelTag = true;
                            tmpU=string.Format("{0}=1",tmpColName);
                        }
                    }
                }
                strN = strN.TrimEnd(",".ToCharArray());
                strN = strN.Replace(",", " and ");
                if (isDelTag)
                {
                    return string.Format("update {0} set {1} where {2}", tmpTabName, tmpU, strN);
                }
                else
                {
                    return string.Format("delete from {0} where {1}", tmpTabName, strN);
                }
            }
            else
            {
                return null;
            }
        }
        private static string FormatValSql(Type type, object val)
        {
            string tmpStr = string.Empty;
            if (type == typeof(bool))
            {
                tmpStr=Convert.ToBoolean(val) ? "1" : "0";
            }
            else
            {
                tmpStr = string.Format("\"{0}\"",val);
            }
            return tmpStr;
        }
    }
}
